<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html lang="zh-CN"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="Content-Language" content="zh-CN"><link href="stylesheet.css" media="all" rel="stylesheet" type="text/css">
<title>区域支持</title>
<script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?d286c55b63a3c54a1e43d10d4c203e75"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script>
</head><body class="SECT1">
<div>
<table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><th colspan="5" align="center" valign="bottom">PostgreSQL 8.2.3 中文文档</th></tr>
<tr><td width="10%" align="left" valign="top"><a href="charset.html" accesskey="P">后退</a></td><td width="10%" align="left" valign="top"><a href="charset.html">快退</a></td><td width="60%" align="center" valign="bottom">章21. 区域</td><td width="10%" align="right" valign="top"><a href="charset.html">快进</a></td><td width="10%" align="right" valign="top"><a href="multibyte.html" accesskey="N">前进</a></td></tr>
</table>
<hr align="LEFT" width="100%"></div>
<div class="SECT1"><h1 class="SECT1"><a name="LOCALE">21.1. 区域支持</a></h1><a name="AEN23549"></a>
<p><i class="FIRSTTERM">区域</i>支持指的是应用中考虑字母、排序、数字格式化等与文化相关的问题。PostgreSQL 使用服务器操作系统提供的标准 ISO C 和 POSIX 区域机制。更多的信息请参考你的系统文档。</p>
<div class="SECT2"><h2 class="SECT2"><a name="AEN23555">21.1.1. 概述</a></h2>
<p>区域支持是在使用 <tt class="COMMAND">initdb</tt> 创建一个数据库集群的时候自动初始化的。缺省时，<tt class="COMMAND">initdb</tt> 将会按照它的执行环境的区域设置初始化数据库集群；因此如果你的系统已经设置为你的数据库集群想要的区域，那么你就没有什么可干的。如果你想使用其它的区域(或者你还不知道你的系统设置的区域是什么)，那么你可以用 <tt class="OPTION">--locale</tt> 命令行选项告诉 <tt class="COMMAND">initdb</tt> 你需要的区域究竟是哪个。比如：</p>
<pre class="SCREEN">initdb --locale=sv_SE</pre>
<p>这个例子就把区域设置为瑞典(<tt class="LITERAL">sv</tt>)，用瑞典语说话(<tt class="LITERAL">SE</tt>)。其它的可能性是 <tt class="LITERAL">en_US</tt>(美国英语)和 <tt class="LITERAL">fr_CA</tt>(加拿大法语)等等。如果有多于一种字符集可以用于区域，那么声明看起来像下面这样：<tt class="LITERAL">cs_CZ.ISO8859-2</tt> 。你的系统里有哪些可用的区域设置，它们的名字是什么，这些信息都取决于你的操作系统提供商提供了什么以及你安装了什么东西。在大多数系统上，命令 <tt class="LITERAL">locale -a</tt> 将提供所有可用区域的一个列表。</p>
<p>有时候，把几种区域规则混合起来也很有用，比如，使用英语字符规则而用西班牙语信息。为了支持这些，我们有一套区域子范畴用于控制区域规则的某一方面：
<div class="INFORMALTABLE"><a name="AEN23571"></a>
<table border="1" class="CALSTABLE"><col><col>
<tbody>
<tr><td><tt class="ENVAR">LC_COLLATE</tt></td><td>字符串排序顺序</td></tr>
<tr><td><tt class="ENVAR">LC_CTYPE</tt></td><td>字符分类(什么是字母?它是这个字母的等效大写?)</td></tr>
<tr><td><tt class="ENVAR">LC_MESSAGES</tt></td><td>信息的语言</td></tr>
<tr><td><tt class="ENVAR">LC_MONETARY</tt></td><td>货币金额的格式</td></tr>
<tr><td><tt class="ENVAR">LC_NUMERIC</tt></td><td>数字的格式</td></tr>
<tr><td><tt class="ENVAR">LC_TIME</tt></td><td>日期和时间的格式</td></tr>
</tbody>
</table>
</div>
这些范畴名转换成 <tt class="COMMAND">initdb</tt> 选项的名字以覆盖某个特定范畴的区域选择。比如，要把区域设置为加拿大法语，但使用美国的货币格式化规则，可以使用 <tt class="LITERAL">initdb --locale=fr_CA --lc-monetary=en_US</tt> 。</p>
<p>如果你想要你的系统表现得像没有区域支持一样，那么使用特殊的区域 <tt class="LITERAL">C</tt> 或 <tt class="LITERAL">POSIX</tt> 。</p>
<p>一些区域范畴的性质是它们的值必需在数据库集群的生命期内固定。也就是说，一旦运行了 <tt class="COMMAND">initdb</tt> 之后，你就再也不能更改它们了。<tt class="LITERAL">LC_COLLATE</tt> 和 <tt class="LITERAL">LC_CTYPE</tt> 就是这样的范畴。它们影响索引的排序顺序，因此它们必需保持固定，否则在文本字段上的索引将会崩溃。PostgreSQL 通过记录 <tt class="COMMAND">initdb</tt> 看到的 <tt class="ENVAR">LC_COLLATE</tt> 和 <tt class="ENVAR">LC_CTYPE</tt> 来强迫这一点。服务器在启动的时候自动使用这两个数值。</p>
<p>其它区域范畴可以在服务器启动的时候根据需要设置运行时配置变量来改变(参阅<a href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">节17.10.2</a>获取细节)。<tt class="COMMAND">initdb</tt> 选择的缺省值实际上只是做为服务器启动缺省写入 <tt class="FILENAME">postgresql.conf</tt> 配置文件。如果你在 <tt class="FILENAME">postgresql.conf</tt> 里面删除了这些缺省值，那么服务器将会继承来自运行环境的设置。</p>
<p>请注意服务器的区域行为是由它看到的环境变量决定的，而不是由客户端的环境变量影响的。因此，我们要在启动服务器之前认真地设置好这些变量。这样带来的一种情况是如果客户端和服务器设置成不同的区域，那么消息可能以不同的语言呈现，实际情况取决于它们的源是什么。</p>
<div class="NOTE">
<blockquote class="NOTE">
<p><b>【注意】</b>在我们谈到从执行环境继承区域的时候，我们的意思是在大多数操作系统上的下列动作：对于一个给定的区域范畴，比如字符集，按照下面的顺序评估这些环境变量，直到找到一个已设置的：<tt class="ENVAR">LC_ALL</tt>, <tt class="ENVAR">LC_COLLATE</tt>(变量对应相应的范畴), <tt class="ENVAR">LANG</tt> 。如果这些环境变量一个都没有设置，那么区域缺省为 <tt class="LITERAL">C</tt> 。</p>
<p>一些信息区域化库也使用环境变量 <tt class="ENVAR">LANGUAGE</tt> ，它覆盖所有其它用于设置语言信息的区域设置。如果有问题，请参考你的操作系统文档，特别是 <span class="APPLICATION">gettext</span> 的文档获取更多信息。</p>
</blockquote>
</div>
<p>要允许将信息翻译成用户选择的语言，制作时必需打开 NLS 选项。这个选项独立于其它区域支持。</p>
</div>
<div class="SECT2"><h2 class="SECT2"><a name="AEN23628">21.1.2. 行为</a></h2>
<p>区域设置特别影响下面的 SQL 特性：</p>
<ul>
<li><p>使用 <tt class="LITERAL">ORDER BY</tt> 和区域的排序</p></li>
<li><p>使用 <tt class="LITERAL">LIKE</tt> 子句的索引能力</p></li>
<li><p><code class="FUNCTION">upper</code>, <code class="FUNCTION">lower</code>, <code class="FUNCTION">initcap</code> 函数</p></li>
<li><p><code class="FUNCTION">to_char</code> 函数族</p></li>
</ul>
<p>PostgreSQL 里使用非 <tt class="LITERAL">C</tt> 或 <tt class="LITERAL">POSIX</tt> 区域的缺点是速度。它降低了字符处理的速度并阻止了在 <tt class="LITERAL">LIKE</tt> 类查询里面普通索引的使用。因此，只有在你实际上需要的时候才使用它。</p>
<p>为了允许 PostgreSQL 在非 C 区域下的 <tt class="LITERAL">LIKE</tt>子句中使用索引，有好几个自定义的操作符类可以用。这些操作符类允许创建一个严格地比较每个字符的索引，而忽略区域比较规则。请参考<a href="indexes-opclass.html">节11.8</a>获取更多信息。</p>
</div>
<div class="SECT2"><h2 class="SECT2"><a name="AEN23670">21.1.3. 问题</a></h2>
<p>如果经过上面解释后区域支持仍然不能运转，那你就要检查一下操作系统的区域支持是否正确配置。要检查某个区域是否安装并且正常运转，你可以使用 <tt class="LITERAL">locale -a</tt> 命令(如果你的系统提供了该命令)。</p>
<p>请检查核实 PostgreSQL 确实使用了你认为它该用的区域设置。<tt class="ENVAR">LC_COLLATE</tt> 和 <tt class="ENVAR">LC_CTYPE</tt> 的设置都是在 <tt class="COMMAND">initdb</tt> 时决定的，如果不重复 <tt class="COMMAND">initdb</tt> 是不可能改变的。其它的区域设置包括 <tt class="ENVAR">LC_MESSAGES</tt> 和 <tt class="ENVAR">LC_MONETARY</tt> 都是由服务器的启动环境决定的，但是可以在运行时修改。你可以用 <tt class="COMMAND">SHOW</tt> 命令检查数据库正在使用的区域设置。</p>
<p><tt class="FILENAME">src/test/locale</tt> 目录包含 PostgreSQL 的区域支持测试套件。</p>
<p>那些通过分析错误信息处理服务器端错误的客户端应用很明显会有问题，因为服务器信息可能会以不同的语言表示。我们建议这类应用的开发人员改用错误代码机制。</p>
<p>维护信息翻译表需要许多志愿者的坚持不懈的努力，他们就是希望 PostgreSQL 以他们的语言说话的人。如果你的语言信息目前还不可用或者没有完全翻译完成，那么我们很欢迎你的协助。如果你想帮忙，那么请参考<a href="nls.html">章46</a>或者向开发者邮递列表发邮件。</p>
</div>
</div>
<div>
<hr align="LEFT" width="100%">
<table summary="Footer navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td width="33%" align="left" valign="top"><a href="charset.html" accesskey="P">后退</a></td><td width="34%" align="center" valign="top"><a href="index.html" accesskey="H">首页</a></td><td width="33%" align="right" valign="top"><a href="multibyte.html" accesskey="N">前进</a></td></tr>
<tr><td width="33%" align="left" valign="top">区域</td><td width="34%" align="center" valign="top"><a href="charset.html" accesskey="U">上一级</a></td><td width="33%" align="right" valign="top">字符集支持</td></tr>
</table>
</div>
</body></html>